/**
 * Combination.java
 * @author: liuex
 * 2008-3-9 ����11:47:07
 *
 * note: 
 */
package org.lex.math.pc;

import org.lex.utils.functor.UnaryFunctor;

public class Combination {
	public static void visitCombination(int n, int r, UnaryFunctor<?, int[]> functor) {
		new Combination(n, r).visit(functor);
	}

	public static int[][] combinations(int n, int r) {
		final int[][] result = new int[PC.combination(n, r)][r];
		Combination.visitCombination(n, r, new UnaryFunctor<Void, int[]>() {
			int i = 0;

			@Override
			public Void operate(int[] data) {
				System.arraycopy(data, 0, result[i], 0, data.length);
				i++;
				return null;
			}
		});
		return result;
	}

	private int n = 0;
	private int r = 0;

	private Combination(int n, int r) {
		this.n = n;
		this.r = r;
	}

	void visit(UnaryFunctor<?, int[]> functor) {
		this.visitCombination(functor, new int[r], n, r, -1, -1);
	}

	private void visitCombination(UnaryFunctor<?, int[]> functor, int a[], int n, int r, int k, int temp) {
		temp++;
		if (temp < r) {
			for (int i = k + 1; i < n; i++) {
				a[temp] = i;// + 1; // ��ֵ
				visitCombination(functor, a, n, r, i, temp); // �ݹ����
			}
		} else {
			functor.operate(a);
		}
	}
}
